'- .mod to hexdump converter
'- copyleft Paulo Silva, oct'20
'-------------------------------
'- bugs:
'-   weird conversion from .mod files with channel amount different than 4 
'-------------------------------

function nttfrq$(freqb)
  e$=   "C-1C#1D-1D#1E-1F-1F#1G-1G#1A-1A#1B-1"
  e$=e$+"C-2C#2D-2D#2E-2F-2F#2G-2G#2A-2A#2B-2"
  e$=e$+"C-3C#3D-3D#3E-3F-3F#3G-3G#3A-3A#3B-3"
  e$=e$+"C-4C#4D-4D#4E-4F-4F#4G-4G#4A-4A#4B-4"
  e$=e$+"C-5C#5D-5D#5E-5F-5F#5G-5G#5A-5A#5B-5"
  e$=e$+"C-6C#6D-6D#6E-6F-6F#6G-6G#6A-6A#6B-6"
  e$=e$+"C-7C#7D-7D#7E-7F-7F#7G-7G#7A-7A#7B-7"
  e$=e$+"C-8C#8D-8D#8E-8F-8F#8G-8G#8A-8A#8B-8..."
  tmq=141-(int((log(freqb*.99)/log(2))*12))
  if tmq<1 then:tmq=1:end if
  if tmq>97 then:tmq=97:end if
  return mid$(e$,(tmq*3)-2,3)
  end function

dim dmp[900000]
dim smplng[64]

finp$="tune.mod"
if argc>2 then:finp$=argv(2):end if
fout2$=finp$+"_hexdump.txt":fout3$=finp$+"_hexdump_debug.txt"

open finp$ for input as #1
open fout2$ for output as #2

bcntr=0
while eof(1)=0 and bcntr<900000:
  brd=readbyte(1)
  dmp[bcntr]=brd
  bcntr+=1
  end while

'- header
print #2,";- .mod hexdump":print #2,""

'- songname
txou$=""
ascou$=""
for rd=1 to 20
  brd=dmp[0+rd-1]
  txou$+=ucase$(right$(hex$(0x100+brd),2))
  if brd>=32 then:
    ascou$+=chr$(brd)
    end if
  next
txou$+=" ;- Songname: \""+ascou$+"\""
print #2,txou$:print #2,""

'- samples
for smpl=1 to 31
  print #2,";Sample "+right$("000"+str$(smpl),2)

  txou$="":ascou$="":valou=0
  for rd=1 to 22
    brd=dmp[20+((smpl-1)*30)+rd-1]
    txou$+=ucase$(right$(hex$(0x100+brd),2))
    if brd>=32 then:
      ascou$+=chr$(brd)
      end if
    next
  txou$+=" ;- Sample Name "+right$("000"+str$(smpl),2)+": \""+ascou$+"\""
  print #2,txou$:

  txou$="":ascou$="":valou=0
  for rd=1 to 2
    brd=dmp[42+((smpl-1)*30)+rd-1]
    txou$+=ucase$(right$(hex$(0x100+brd),2))
    valou=(valou*256)+brd
    next
  smplng[smpl]=valou
  txou$+=" ;- Sample Lenght "+right$("000"+str$(smpl),2)+": "+str$(valou*2)
  print #2,txou$

  txou$="":ascou$="":valou=0
  for rd=1 to 1
    brd=dmp[44+((smpl-1)*30)+rd-1]
    txou$+=ucase$(right$(hex$(0x100+brd),2))
    valou=(valou*256)+brd
    next
  txou$+=" ;- Sample Finetune "+right$("000"+str$(smpl),2)+": "+str$(((valou+8)mod 16)-8) 
  print #2,txou$

  txou$="":ascou$="":valou=0
  for rd=1 to 1
    brd=dmp[45+((smpl-1)*30)+rd-1]
    txou$+=ucase$(right$(hex$(0x100+brd),2))
    valou=(valou*256)+brd
    next
  txou$+=" ;- Sample Volume "+right$("000"+str$(smpl),2)+": "+str$(valou)
  print #2,txou$

  txou$="":ascou$="":valou=0
  for rd=1 to 2
    brd=dmp[46+((smpl-1)*30)+rd-1]
    txou$+=ucase$(right$(hex$(0x100+brd),2))
    valou=(valou*256)+brd
    next
  txou$+=" ;- Sample Repeat Point "+right$("000"+str$(smpl),2)+": "+str$(valou*2)
  print #2,txou$

  txou$="":ascou$="":valou=0
  for rd=1 to 2
    brd=dmp[48+((smpl-1)*30)+rd-1]
    txou$+=ucase$(right$(hex$(0x100+brd),2))
    valou=(valou*256)+brd
    next
  txou$+=" ;- Sample Repeat Lenght "+right$("000"+str$(smpl),2)+": "+str$(valou*2)
  print #2,txou$

  print #2,""
  next

txou$="":ascou$="":valou=0
for rd=1 to 1
  brd=dmp[950+rd-1]
  txou$+=ucase$(right$(hex$(0x100+brd),2))
  valou=(valou*256)+brd
  next
txou$+=" ;- Song Lenght: "
print #2,txou$

txou$="":ascou$="":valou=0
for rd=1 to 1
  brd=dmp[951+rd-1]
  txou$+=ucase$(right$(hex$(0x100+brd),2))
  valou=(valou*256)+brd
  next
txou$+=" ;- Flag: "
print #2,txou$
print #2,""

'- song positions
mxptn=0
print #2,";- Song Positions:"
for smpl=1 to 128 step 8
  'print #2,";Sample "+str$(smpl)
  txou$="":ascou$="":valou=0
  for rd=1 to 8
    brd=dmp[952+((smpl-1)*1)+rd-1]
    if brd>=mxptn then:mxptn=brd:end if
    txou$+=ucase$(right$(hex$(0x100+brd),2))+" "
    next
  'txou$+=" ;- Name: \""+ascou$+"\""
  print #2,txou$:
  next
print #2,""

'- signature
txou$="":ascou$="":valou=0
for rd=1 to 4
  brd=dmp[1080+rd-1]
  txou$+=ucase$(right$(hex$(0x100+brd),2))+" "
  if brd>=32 then:
    ascou$+=chr$(brd)
    end if
  next
print #2,txou$+" ;- Signature: \""+ascou$+"\""
print #2,""

sgnt1$=ascou$
chanamt=4
if sgnt1$="M.K." then:
  chanamt=4
  end if
if right$(sgnt1$,3)="CHN" or right$(sgnt1$,3)="FLT" then:
  chanamt=val(mid$(sgnt1$,1,1))
  end if
if right$(sgnt1$,2)="CH" or right$(sgnt1$,2)="FL" then:
  chanamt=(val(mid$(sgnt1$,1,1)))*10+(val(mid$(sgnt1$,2,1)))
  end if

txoutpt$=";-|"
for iqq=0 to chanamt-1
  txoutpt$+=" ... .. ... |"
  next


'- patterns
print #2,";- Patterns:":print #2,""
for patrn=0 to mxptn

  print #2,";Pattern "+ucase$( right$( hex$(0x100+patrn) ,2) )
  for rowl=0 to 63
    txou$="":ascou$="":valou=0
    'txoub$=";-| ... .. ... | ... .. ... | ... .. ... | ... .. ... |"
    txoub$=txoutpt$
    for rdr=0 to chanamt-1

      vlq0=dmp[1084+(patrn*(chanamt*256))+0+(rdr*4)+(rowl*(chanamt*4))]
      vlq1=dmp[1084+(patrn*(chanamt*256))+1+(rdr*4)+(rowl*(chanamt*4))]
      vlq2=dmp[1084+(patrn*(chanamt*256))+2+(rdr*4)+(rowl*(chanamt*4))]
      vlq3=dmp[1084+(patrn*(chanamt*256))+3+(rdr*4)+(rowl*(chanamt*4))]
      vfrq=  (bitwiseand (vlq0,15)*256)+vlq1
      vsmp=  (bitwiseand (vlq0,240))+(bitwiseand (vlq2,240)/16)
      veff=  (bitwiseand (vlq2,15)*256)+vlq3
      if vfrq<>0 then:
        txoub$= replace$(4+(13*rdr),txoub$,nttfrq$(vfrq))
        end if
      if vsmp<>0 then:
        txoub$= replace$(8+(13*rdr),txoub$,ucase$(right$( hex$(0x1000+vsmp ),2)))
        end if
      if veff<>0 then:
        txoub$= replace$(11+(13*rdr),txoub$,ucase$(right$( hex$(0x1000+veff ),3)))
        end if

      for rdn=0 to 3
        brd=dmp[1084+(patrn*(chanamt*256))+rdn+(rdr*4)+(rowl*(chanamt*4))]
        txou$+=ucase$(right$(hex$(0x100+brd),2))
        next
      txou$+=" "
      next
    txou$+=txoub$
    print #2,txou$:
    next
  print #2,""
  next

adrsmp=1084+((mxptn+1)*(chanamt*256))

close #1
open finp$ for input as #1

for zrd=1 to adrsmp
  zdum=readbyte(1)
  next

'- samples
print #2,";- Samples:":
print #2,""

for smpl=1 to 31
  print #2,";Sample Hexdump "+right$("000"+str$(smpl),2)
  txou$="":ascou$="":valou=0
  for rd=0 to (smplng[smpl]*2)-1
    brd=readbyte(1)
    txou$+=ucase$(right$(hex$(0x100+brd),2))
    if bitwiseand (rd,31)=31 then:
      print #2,txou$
      txou$=""
      end if
    next
  print #2,txou$
  print #2,""
  next


print #2,""
print #2,";- end of file"
print #2,""

close #1:close #2





